package cz.test;

import cz.javabean.Customer;
import cz.javabean.LinkMan;
import cz.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

/**
 * @Title: HibernateDemo1
 * @Description: cz.test
 * @Auther: Jason.Song
 * @Version: 1.0
 *
 *
 */
public class HibernateDemo1 {
    /*向数据库中添加数据,并且构建两张表的关系*/
    @Test
    public void demo1() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction ts = session.beginTransaction();

        //插入customer的数据
        Customer customer1 = new Customer();
        customer1.setCust_name("王菲");
        Customer customer2 = new Customer();
        customer2.setCust_name("王思聪");


        //插入三个联系人
        LinkMan linkMan1 = new LinkMan();
        linkMan1.setLkm_name("霆锋");
        LinkMan linkMan2 = new LinkMan();
        linkMan2.setLkm_name("雪儿");
        LinkMan linkMan3 = new LinkMan();
        linkMan3.setLkm_name("芙蓉");

        //双向建立关系
        customer1.getLinkMans().add(linkMan1);
        customer2.getLinkMans().add(linkMan2);
        customer2.getLinkMans().add(linkMan3);
        linkMan1.setCustomer(customer1);
        linkMan2.setCustomer(customer2);
        linkMan3.setCustomer(customer2);

        //向两个数据表调价数据
        session.save(customer1);
        session.save(customer2);
        session.save(linkMan1);
        session.save(linkMan2);
        session.save(linkMan3);


        ts.commit();
    }

    @Test
    public void demo2() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction ts = session.beginTransaction();
        //插入customer的数据
        Customer customer1 = new Customer();    //瞬时态
        customer1.setCust_name("王菲");
        //插入联系人
        LinkMan linkMan1 = new LinkMan();
        linkMan1.setLkm_name("霆锋");
        //双向建立关系
        customer1.getLinkMans().add(linkMan1);
        linkMan1.setCustomer(customer1);
        //通过保存一条数据,来同时将与他有关系的表中的数据也保持上去
        session.save(customer1);    //  customer1对象是什么状态的对象 ?  持久态了
        session.save(linkMan1);   //  linkman对象此时依然是瞬时态   TransientObjectException(瞬时态对象异常错误)
        ts.commit();
    }



    /*建立关系之后,做级联保存的设置方法
    * 要有主导方
    * */

    @Test
    public void demo3() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction ts = session.beginTransaction();
        //插入customer的数据
        Customer customer1 = new Customer();    //瞬时态
        customer1.setCust_name("王菲");
        //插入联系人
        LinkMan linkMan1 = new LinkMan();
        linkMan1.setLkm_name("霆锋");
        //双向建立关系
        customer1.getLinkMans().add(linkMan1);
        linkMan1.setCustomer(customer1);

        //完成级联的添加过程
        session.save(linkMan1);
        ts.commit();
    }

    /* 一对多的两张表上都做了级联操作的设置*/
    @Test
    public void demo4() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction ts = session.beginTransaction();
        //插入customer的数据
        Customer customer1 = new Customer();    //瞬时态
        customer1.setCust_name("王菲");
        //插入联系人
        LinkMan linkMan1 = new LinkMan();
        linkMan1.setLkm_name("霆锋");
        LinkMan linkMan2 = new LinkMan();
        linkMan2.setLkm_name("亚鹏");
        LinkMan linkMan3 = new LinkMan();
        linkMan3.setLkm_name("窦唯");
        //双向建立关系
        customer1.getLinkMans().add(linkMan2);
        customer1.getLinkMans().add(linkMan3);
        linkMan1.setCustomer(customer1);


        //session.save(linkMan1);    //hibernate会发送几条insert语句? 4
        //session.save(customer1);       //3条insert语句
        session.save(linkMan3);         // 1
        ts.commit();
    }


    /*删除客户,将联系人外键置null,联系人不被删除*/
    @Test
    public void demo5() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction ts = session.beginTransaction();
        //先查询,再删除客户
        Customer customer = session.get(Customer.class, 2l);
        session.delete(customer);   //通过级联,我们知道删除时先将关联的联系人中的外键设置为null,然后再去删除客户

        ts.commit();
    }

    /*删除客户,同时也删除联系人(实际项目中我们一般是删除一的一方)*/
    @Test
    public void demo6() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction ts = session.beginTransaction();

        Customer customer = session.get(Customer.class, 3l);
        session.delete(customer);

        ts.commit();
    }


    /*双向维护,去除多余的sql语句
    *
    *   两张表中有一方放弃对外键的控制,我们一般是一的一方放弃对外键的控制
    * */
    @Test
    public void demo7() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction ts = session.beginTransaction();

        //让王菲和芙蓉匹配相互的关系
        //取出两个对象
        Customer customer = session.get(Customer.class, 1l);
        LinkMan linkMan = session.get(LinkMan.class, 2l);

        customer.getLinkMans().add(linkMan);
        linkMan.setCustomer(customer);

        //持久态对象可以借助一级缓存的快照区,不用再调用session的update方法

        ts.commit();
    }


    /*cascade : 控制级联添加创建, inverse :控制是否建立外键(对外键的控制)*/
    @Test
    public void demo8() {
        Session session = HibernateUtil.getCurrentSession();
        Transaction ts = session.beginTransaction();

        Customer customer = new Customer();
        LinkMan linkMan = new LinkMan();
        customer.setCust_name("宝强");
        linkMan.setLkm_name("马蓉");

        //关系的建立

        customer.getLinkMans().add(linkMan);

        session.save(customer);


        ts.commit();
    }
}
